﻿using Farming.Domain;
using Microsoft.EntityFrameworkCore.Diagnostics;
using Microsoft.EntityFrameworkCore;
using IdentityModel;

namespace Farming.WebApi
{
    public sealed class SoftDeleteInterceptor : SaveChangesInterceptor
    {
        private readonly IHttpContextAccessor httpContextAccessor;
        private static string userName;
        private static string userId;
        public SoftDeleteInterceptor(IHttpContextAccessor httpContextAccessor)
        {
            this.httpContextAccessor = httpContextAccessor;
            userName = httpContextAccessor.HttpContext.User.FindFirst(JwtClaimTypes.Name)?.Value;
            userId = httpContextAccessor.HttpContext.User.FindFirst(JwtClaimTypes.Id)?.Value;

        }
        
        public override InterceptionResult<int> SavingChanges(DbContextEventData eventData, InterceptionResult<int> result)
        {
            OnSavingChanges(eventData);
            return base.SavingChanges(eventData, result);
        }

        public override ValueTask<InterceptionResult<int>> SavingChangesAsync(DbContextEventData eventData, InterceptionResult<int> result,
            CancellationToken cancellationToken = new CancellationToken())
        {
            OnSavingChanges(eventData);
            return base.SavingChangesAsync(eventData, result, cancellationToken);
        }

        private static void OnSavingChanges(DbContextEventData eventData)
        {
            ArgumentNullException.ThrowIfNull(eventData.Context);
            eventData.Context.ChangeTracker.DetectChanges();
            foreach (var entityEntry in eventData.Context.ChangeTracker.Entries())
            {
                if(entityEntry.Entity is IAuditFields soft)
                {
                    if (entityEntry is { State: EntityState.Deleted})
                    {
                        soft.IsDeleted = true;
                        soft.DeleterName = userName;
                        soft.DeleteTime = DateTime.Now;
                        entityEntry.State = EntityState.Modified;
                    }
                    if (entityEntry is { State: EntityState.Modified })
                    {
                        soft.LastModifierName = userName;
                        soft.LastModifyTime = DateTime.Now;
                    }
                    if (entityEntry.State == EntityState.Added)
                    {
                        soft.CreaterName = userName;
                        soft.CreateTime = DateTime.Now;
                    }


                }
                
            }
        }
    }
}
